<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="论文精读——TextAttack&amp;&amp;OpenAttack, J Sir">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>论文精读——TextAttack&amp;&amp;OpenAttack | J Sir</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 6.0.0">
<style>.github-emoji { position: relative; display: inline-block; width: 1.2em; min-height: 1.2em; overflow: hidden; vertical-align: top; color: transparent; }  .github-emoji > span { position: relative; z-index: 10; }  .github-emoji img, .github-emoji .fancybox { margin: 0 !important; padding: 0 !important; border: none !important; outline: none !important; text-decoration: none !important; user-select: none !important; cursor: auto !important; }  .github-emoji img { height: 1.2em !important; width: 1.2em !important; position: absolute !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; user-select: none !important; cursor: auto !important; } .github-emoji-fallback { color: inherit; } .github-emoji-fallback img { opacity: 0 !important; }</style>
</head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">J Sir</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>留言板</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">J Sir</div>
        <div class="logo-desc">
            
            Never really desperate, only the lost of the soul.
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			留言板
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://github.com/jy741" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://github.com/jy741" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/1.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">论文精读——TextAttack&amp;&amp;OpenAttack</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/%E5%AF%B9%E6%8A%97%E6%94%BB%E5%87%BB/">
                                <span class="chip bg-color">对抗攻击</span>
                            </a>
                        
                            <a href="/tags/%E6%9C%9F%E5%88%8A%E8%AE%BA%E6%96%87/">
                                <span class="chip bg-color">期刊论文</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2023-04-22
                </div>
                

                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    7.8k
                </div>
                

                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>
        </div>
        <hr class="clearfix">

        
        <!-- 是否加载使用自带的 prismjs. -->
        <link rel="stylesheet" href="/libs/prism/prism.css">
        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <h1 id="TextAttack"><a href="#TextAttack" class="headerlink" title="TextAttack"></a>TextAttack</h1><p>原文标题：《TextAttack: A Framework for Adversarial Attacks, Data Augmentation, and Adversarial Training in NLP》</p>
<p>2020 EMNLP</p>
<h2 id="摘要"><a href="#摘要" class="headerlink" title="摘要"></a>摘要</h2><p>尽管已经有大量研究使用对抗性攻击来分析 NLP 模型，但每种攻击都是在其自己的代码库中实施的。开发 NLP 攻击并利用它们来提高模型性能仍然具有挑战性。本文介绍了 TextAttack，这是一个用于 NLP 中的对抗性攻击、数据增强和对抗性训练的 Python 框架。 </p>
<p>TextAttack 从四个部分构建攻击：一个目标函数、一组约束、一个转换和一个搜索方法。 TextAttack 的模块化设计使研究人员能够轻松地从新组件和现有组件的组合中构建攻击。 TextAttack 还包括数据增强和对抗性训练模块，用于使用对抗性攻击的组件来提高模型的准确性和稳健性。</p>
<p>代码地址：<a target="_blank" rel="noopener" href="https://github.com/QData/TextAttack">https://github.com/QData/TextAttack</a></p>
<span id="more"></span>
<h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>在过去几年中，人们越来越关注研究 NLP 模型的对抗性鲁棒性，包括生成对抗性示例的新方法和更好的防御这些对手的方法，但很难直接和公平地比较这些攻击，因为它们通常是在不同的数据样本和被攻击模型上进行评估的。由于缺少源代码，将以前的工作重新实现耗时且容易出错，而且有不少遗漏的实现细节。这些障碍使基准比较难以信任，严重阻碍了该领域的发展。</p>
<p>为了将对抗性攻击方法统一到一个系统中，我们将 NLP 攻击分解为四个部分：目标函数、一组约束、转换和搜索方法。</p>
<p>攻击试图扰乱输入文本，使模型输出满足目标函数（即指示攻击是否成功）并且扰动遵守约束集（例如，语法约束、语义相似性约束）。搜索方法用于查找产生成功的对抗性示例的一系列转换。</p>
<p>这种模块化设计使我们能够轻松地从文献中组装攻击，同时重用在攻击之间共享的组件。</p>
<p>TextAttack 为文献中的 16 种对抗性攻击提供了清晰、可读的实现。首次可以在标准化环境中对这些攻击进行基准测试、比较和分析。</p>
<p>TextAttack 直接与 HuggingFace 的转换器和 nlp 库集成。这允许用户测试对模型和数据集的攻击。 TextAttack 在各种流行的数据集上提供了数十种预训练模型（LSTM、CNN 和各种基于 transformer 的模型）。目前，TextAttack 支持多种任务，包括摘要、机器翻译和 GLUE 基准测试中的所有九个任务。 TextAttack 还允许用户提供自己的模型和数据集。</p>
<p>TextAttack 为数据增强和对抗训练提供了易于使用的工具。 TextAttack 的 Augmenter 类使用转换和一组约束来生成用于数据扩充的新样本。</p>
<p>TextAttack主要用途：</p>
<ol>
<li>对标准化模型和数据集之前的工作进行基准测试和比较 NLP 攻击。</li>
<li>通过重用丰富的可用模块快速开发 NLP 攻击方法。</li>
<li>对提议的攻击和数据增强方法的各个组件进行消融研究。</li>
<li>在增强数据集上训练模型。</li>
<li>利用文献中的攻击进行对抗性训练，以提高模型的稳健性。</li>
</ol>
<h2 id="TextAttack框架"><a href="#TextAttack框架" class="headerlink" title="TextAttack框架"></a>TextAttack框架</h2><p>TextAttack 旨在实施攻击，在给定 NLP 模型的情况下，找到满足攻击目标并遵守特定语言约束的输入序列的扰动。攻击者必须在所有潜在的转换中进行搜索，以找到一系列能够生成成功的对抗样本的转换。</p>
<p>每次攻击都可以由四个部分构成：</p>
<ol>
<li>一个特定于任务的目标函数，它根据模型输出确定攻击是否成功。（如非目标分类、目标分类、非重叠输出、最小 BLEU 分数）</li>
<li>一组约束，用于确定扰动对于原始输入是否有效。（如最大词嵌入距离、词性一致性、语法检查器、最小句子编码余弦相似度）</li>
<li>在给定输入的情况下生成一组潜在扰动的转换。（如词嵌入词交换、词库词交换、同形字符替换）</li>
<li>一种方法，可以连续查询模型并从一组转换中选择有希望的扰动。（如贪婪词重要性排名、波束搜索、遗传算法）</li>
</ol>
<h3 id="目标函数"><a href="#目标函数" class="headerlink" title="目标函数"></a>目标函数</h3><p>目标函数采用输入 x’ 并确定它是否满足对原始输入 x 进行成功攻击的条件。</p>
<p>目标函数因任务而异。例如，对于分类任务，一次成功的对抗性攻击可能会将模型的输出更改为某个标签。目标函数还对给定的 x’ 对于实现预期目标的“好”程度进行评分，搜索方法可以使用该评分作为寻找最佳解决方案的启发式方法。</p>
<p>TextAttack 包括以下目标函数：</p>
<ul>
<li>非目标分类：最小化正确分类标签的得分</li>
<li>目标分类：最大化所选错误分类标签的分数</li>
<li>输入减少（分类）：将输入文本减少到尽可能少的单词，同时保持相同的预测标签</li>
<li>非重叠输出（文本到文本）：更改输出文本，使其中没有任何单词与原始输出文本重叠</li>
<li>最小化 BLEU 分数（文本到文本）：更改输出文本，使其与原始输出文本之间的 BLEU 分数最小化</li>
</ul>
<h3 id="约束"><a href="#约束" class="headerlink" title="约束"></a>约束</h3><p>扰乱的文本只有在满足每个攻击的约束条件时才被认为是有效的。 TextAttack 包含四类约束。</p>
<ol>
<li>预转换约束：这些约束用于先发制人地限制 x 的扰动方式，并在 x 受到扰动之前应用。<ul>
<li>停用词修改：停用词不能被扰乱</li>
<li>重复修改：已经被打乱的单词不能再被打乱了</li>
<li>最小字长：不能扰乱小于一定长度的字</li>
<li>最大单词索引修改：超过某个索引的单词不能被干扰</li>
<li>输入列修改：对于文本蕴含等输入可能由两部分组成（例如假设和前提）的任务，我们可以限制我们可以转换的部分（例如假设）</li>
</ul>
</li>
<li>重叠约束：我们在字符级别使用以下指标来测量 x 和 x_adv 之间的重叠，并要求它低于某个阈值作为约束。</li>
<li>语法约束：这些约束通常旨在防止攻击产生扰动，从而引入语法错误。<ul>
<li>语法错误的最大数量</li>
<li>词性一致性：替换词应与原始词具有相同的词性。</li>
<li>根据已研究的语言模型过滤掉不适合上下文的单词</li>
</ul>
</li>
<li>语义约束：试图保留 x 和 x_adv 之间的语义。</li>
</ol>
<h3 id="转换"><a href="#转换" class="headerlink" title="转换"></a>转换</h3><p>转换接受输入并返回一组潜在的扰动。转换与目标函数和约束无关：它返回所有潜在的转换。</p>
<p>TextAttack支持以下转换：</p>
<ul>
<li>在反拟合嵌入空间中与最近邻词交换</li>
<li>WordNet 词交换</li>
<li>掩码语言模型提出的词交换</li>
<li>基于梯度的单词交换</li>
<li>转换字符的单词交换<ul>
<li>删除字符</li>
<li>交换相邻字符</li>
<li>插入随机字符</li>
<li>替换为随机字符</li>
<li>字符替换为同形字符</li>
<li>字符替换为键盘上的相邻字符</li>
</ul>
</li>
<li>单词删除 </li>
<li>单词与词汇表中具有相同词性和义原的另一个单词交换，其中义原由知网获得</li>
<li>复合转换：返回多个转换的结果</li>
</ul>
<h3 id="搜索方法"><a href="#搜索方法" class="headerlink" title="搜索方法"></a>搜索方法</h3><p>搜索方法旨在找到实现目标并满足所有约束的扰动。</p>
<p>TextAttack支持以下搜索方法：</p>
<ul>
<li>带有单词重要性排名的贪婪搜索：根据某种排名函数对所有单词进行排名，按重要性递减的顺序一次交换一个单词。</li>
<li>波束搜索：最初对所有可能的转换进行评分，采用前 b 个转换（其中 b 是称为“波束宽度”的超参数）并迭代，查看波束中所有序列的潜在转换。</li>
<li>贪婪搜索：最初对输入中所有位置的转换进行评分。交换单词，首先进行得分最高的转换。 （这可以看作是束搜索的情况，其中 b = 1）。</li>
<li>遗传算法：通过每个种群成员的贪婪扰动和种群数量之间的交叉，迭代地改变种群，优先选择种群中更成功的成员。</li>
<li>粒子群优化算法：基于种群的进化计算范式利用相互作用的个体种群在特定空间中迭代搜索最优解。</li>
</ul>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230422222003617.png" alt="image-20230422222003617"></p>
<h2 id="开发NLP攻击"><a href="#开发NLP攻击" class="headerlink" title="开发NLP攻击"></a>开发NLP攻击</h2><p>TextAttack 可以作为从 PyPI 安装的 Python 包获得，也可以通过直接从 GitHub 下载获得。</p>
<p>Python 用户可以通过创建和操作 Attack 对象来测试攻击。命令行 API 提供 textattack 攻击，允许用户从其四个组件或单个攻击配方中指定攻击，并在不同的模型和数据集上测试它们。</p>
<p><img src="https://github.com/QData/TextAttack/raw/master/docs/_static/imgs/overview.png" alt="TextAttack Overview"></p>
<h3 id="使用攻击方法对现有攻击进行基准测试"><a href="#使用攻击方法对现有攻击进行基准测试" class="headerlink" title="使用攻击方法对现有攻击进行基准测试"></a>使用攻击方法对现有攻击进行基准测试</h3><p>TextAttack 的模块化设计使我们能够在共享框架中实施许多与过去工作不同的攻击，通常只需添加一两个新组件即可。</p>
<p>所有TextAttack支持的16种攻击都在 TextAttack 中实现为“攻击配方(recipes)”，并且只需一个命令即可进行基准测试。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>——————  攻击策略 ——————</th>
<th>—————— 目标函数 ——————</th>
<th>——————   约束条件 ——————</th>
<th>——————  变换方式 ——————</th>
<th>——————— 搜索方法 ———————</th>
<th><strong>主要思想</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>对于分类任务的攻击策略，例如情感分类和文本蕴含任务：</strong></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><code>alzantot</code></td>
<td>无目标 {分类，蕴含}</td>
<td>被扰动词的比例，语言模型的困惑度，词嵌入的距离</td>
<td>Counter-fitted 词嵌入替换</td>
<td>遗传算法</td>
<td>来自 (<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1804.07998">“Generating Natural Language Adversarial Examples” (Alzantot et al., 2018)</a>)</td>
</tr>
<tr>
<td><code>bae</code></td>
<td>无目标 分类</td>
<td>USE 通用句子编码向量的 cosine 相似度</td>
<td>BERT 遮罩词预测</td>
<td>对 WIR 的贪心搜索</td>
<td>使用 BERT 语言模型作为变换的攻击方法，来自 (<a target="_blank" rel="noopener" href="https://arxiv.org/abs/2004.01970">“BAE: BERT-based Adversarial Examples for Text Classification” (Garg &amp; Ramakrishnan, 2019)</a>).</td>
</tr>
<tr>
<td><code>bert-attack</code></td>
<td>无目标 分类</td>
<td>USE 通用句子编码向量的 cosine 相似度, 被扰动词的最大数量</td>
<td>BERT 遮罩词预测 (包括对 subword 的扩充)</td>
<td>对 WIR 的贪心搜索</td>
<td>(<a target="_blank" rel="noopener" href="https://arxiv.org/abs/2004.09984">“BERT-ATTACK: Adversarial Attack Against BERT Using BERT” (Li et al., 2020)</a>)</td>
</tr>
<tr>
<td><code>checklist</code></td>
<td>{无目标，有目标} 分类</td>
<td>checklist 距离</td>
<td>简写，扩写，以及命名实体替换</td>
<td>对 WIR 的贪心搜索</td>
<td>CheckList 中实现的不变性检验(<a target="_blank" rel="noopener" href="https://arxiv.org/abs/2005.04118">“Beyond Accuracy: Behavioral Testing of NLP models with CheckList” (Ribeiro et al., 2020)</a>)</td>
</tr>
<tr>
<td><code>clare (*coming soon*)</code></td>
<td>无目标 {分类，蕴含}</td>
<td>RoBERTa 掩码语言模型</td>
<td>词的替换，插入，合并</td>
<td>贪心搜索</td>
<td><a target="_blank" rel="noopener" href="https://arxiv.org/abs/2009.07502">“Contextualized Perturbation for Textual Adversarial Attack” (Li et al., 2020)</a>)</td>
</tr>
<tr>
<td><code>deepwordbug</code></td>
<td>{无目标，有目标} 分类</td>
<td>Levenshtein 编辑距离</td>
<td>{字符的插入，删除，替换，以及临近字符交换}</td>
<td>对 WIR 的贪心搜索</td>
<td>贪心搜索 replace-1 分数，多种变换的字符交换式的攻击 (<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1801.04354">“Black-box Generation of Adversarial Text Sequences to Evade Deep Learning Classifiers” (Gao et al., 2018)</a></td>
</tr>
<tr>
<td><code>fast-alzantot</code></td>
<td>无目标 {分类，蕴含}</td>
<td>被扰动词的比例，语言模型的困惑度，词嵌入的距离</td>
<td>Counter-fitted 词嵌入替换</td>
<td>遗传算法</td>
<td>改进过的更快的 Alzantot et al. 遗传算法, 来自 (<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1909.00986">“Certified Robustness to Adversarial Word Substitutions” (Jia et al., 2019)</a>)</td>
</tr>
<tr>
<td><code>hotflip</code> (word swap)</td>
<td>无目标 分类</td>
<td>词嵌入的 cosine 相似度，词性的匹配，被扰动词的数量</td>
<td>基于梯度的词的交换</td>
<td>束搜索</td>
<td>(<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1712.06751">“HotFlip: White-Box Adversarial Examples for Text Classification” (Ebrahimi et al., 2017)</a>)</td>
</tr>
<tr>
<td><code>iga</code></td>
<td>无目标 {分类，蕴含}</td>
<td>被扰动词的比例，词嵌入的距离</td>
<td>Counter-fitted 词嵌入替换</td>
<td>遗传算法</td>
<td>改进的基于遗传算法的词替换，来自 (<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1909.06723">“Natural Language Adversarial Attacks and Defenses in Word Level (Wang et al., 2019)”</a></td>
</tr>
<tr>
<td><code>input-reduction</code></td>
<td>输入归约</td>
<td></td>
<td>词的删除</td>
<td>对 WIR 的贪心搜索</td>
<td>基于词重要性排序的贪心攻击方法，在缩减输入词的同时保持预测结果不变 (<a target="_blank" rel="noopener" href="https://arxiv.org/pdf/1804.07781.pdf">“Pathologies of Neural Models Make Interpretation Difficult” (Feng et al., 2018)</a>)</td>
</tr>
<tr>
<td><code>kuleshov</code></td>
<td>无目标 分类</td>
<td>Thought vector 编码的 cosine 相似度, 语言模型给出的相似度概率</td>
<td>Counter-fitted 词嵌入替换</td>
<td>贪心的词的替换</td>
<td>(<a target="_blank" rel="noopener" href="https://openreview.net/pdf?id=r1QZ3zbAZ">“Adversarial Examples for Natural Language Classification Problems” (Kuleshov et al., 2018)</a>)</td>
</tr>
<tr>
<td><code>pruthi</code></td>
<td>无目标 分类</td>
<td>词的最短长度，被扰动词的最大数量</td>
<td>{临近字符替换，字符的插入与删除，基于键盘字符位置的字符替换}</td>
<td>贪心搜索</td>
<td>模拟常见的打字错误 (<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1905.11268">“Combating Adversarial Misspellings with Robust Word Recognition” (Pruthi et al., 2019)</a></td>
</tr>
<tr>
<td><code>pso</code></td>
<td>无目标 分类</td>
<td></td>
<td>基于 HowNet 的词替换</td>
<td>粒子群优化算法</td>
<td>(<a target="_blank" rel="noopener" href="https://www.aclweb.org/anthology/2020.acl-main.540/">“Word-level Textual Adversarial Attacking as Combinatorial Optimization” (Zang et al., 2020)</a>)</td>
</tr>
<tr>
<td><code>pwws</code></td>
<td>无目标 分类</td>
<td></td>
<td>基于 WordNet 的同义词替换</td>
<td>对 WIR 的贪心搜索</td>
<td>贪心的攻击方法，基于词重要性排序，词的显著性，以及同义词替换分数(<a target="_blank" rel="noopener" href="https://www.aclweb.org/anthology/P19-1103/">“Generating Natural Language Adversarial Examples through Probability Weighted Word Saliency” (Ren et al., 2019)</a>)</td>
</tr>
<tr>
<td><code>textbugger</code> : (black-box)</td>
<td>无目标 分类</td>
<td>USE 通用句子编码向量的 cosine 相似度</td>
<td>{字符的插入、删除、替换，以及临近字符交换}</td>
<td>对 WIR 的贪心搜索</td>
<td>([(<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1812.05271">“TextBugger: Generating Adversarial Text Against Real-world Applications” (Li et al., 2018)</a>).</td>
</tr>
<tr>
<td><code>textfooler</code></td>
<td>无目标 {分类，蕴含}</td>
<td>词嵌入的距离，词性的匹配，USE 通用句子编码向量的 cosine 相似度</td>
<td>Counter-fitted 词嵌入替换</td>
<td>对 WIR 的贪心搜索</td>
<td>对词重要性排序的贪心攻击方法(<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1907.11932">“Is Bert Really Robust?” (Jin et al., 2019)</a>)</td>
</tr>
<tr>
<td><strong>对 seq2seq 模型的攻击策略：</strong></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><code>morpheus</code></td>
<td>最小 BLEU 分数</td>
<td></td>
<td>词的屈折变化</td>
<td>贪心搜索</td>
<td>贪心的用词的屈折变化进行替换，来最小化 BLEU 分数(<a target="_blank" rel="noopener" href="https://www.aclweb.org/anthology/2020.acl-main.263.pdf">“It’s Morphin’ Time! Combating Linguistic Discrimination with Inflectional Perturbations”</a></td>
</tr>
<tr>
<td><code>seq2sick</code> :(black-box)</td>
<td>翻译结果无重叠</td>
<td></td>
<td>Counter-fitted 词嵌入替换</td>
<td>对 WIR 的贪心搜索</td>
<td>贪心攻击方法，以改变全部的翻译结果为目标。目前实现的是黑盒攻击，计划改为与论文中一样的白盒攻击(<a target="_blank" rel="noopener" href="https://arxiv.org/abs/1803.01128">“Seq2Sick: Evaluating the Robustness of Sequence-to-Sequence Models with Adversarial Examples” (Cheng et al., 2018)</a>)</td>
</tr>
</tbody>
</table>
</div>
<blockquote>
<p>WIR 为 word word importance ranking 的缩写，即词重要性排序。</p>
</blockquote>
<p>下图为重新实施的攻击与原始源代码在成功率（左）和扰动词百分比（右）方面的比较。未在文献中找到的数字标记为“-”。</p>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230422222211160.png" alt="image-20230422222211160"></p>
<h3 id="通过结合新的和现有的组件创建新的攻击"><a href="#通过结合新的和现有的组件创建新的攻击" class="headerlink" title="通过结合新的和现有的组件创建新的攻击"></a>通过结合新的和现有的组件创建新的攻击</h3><p>从上表可以看出，许多组件在 NLP 攻击之间共享。新的攻击通常会重用过去工作中的组件，添加一两个新的部分。 TextAttack 允许研究人员专注于新组件的生成，而不是复制过去的结果。</p>
<p>如果研究人员希望尝试应用 TextFooler 的搜索方法、转换和约束来攻击翻译模型，他们只需要在 TextAttack 中实现翻译目标函数即可。</p>
<h3 id="评估对TextAttack预训练模型的攻击"><a href="#评估对TextAttack预训练模型的攻击" class="headerlink" title="评估对TextAttack预训练模型的攻击"></a>评估对TextAttack预训练模型的攻击</h3><p>TextAttack 为用户提供了 82 个预训练模型，包括词级 LSTM、词级 CNN、BERT 以及其他基于 transformer 的模型，这些模型在 HuggingFace nlp 提供的各种数据集上进行了预训练。</p>
<h2 id="利用TextAttack改进NLP模型"><a href="#利用TextAttack改进NLP模型" class="headerlink" title="利用TextAttack改进NLP模型"></a>利用TextAttack改进NLP模型</h2><h3 id="评估自定义模型的稳健性"><a href="#评估自定义模型的稳健性" class="headerlink" title="评估自定义模型的稳健性"></a>评估自定义模型的稳健性</h3><p>TextAttack 与模型无关——这意味着它可以对在任何深度学习框架中实现的模型进行攻击。模型对象必须能够接受一个字符串（或字符串列表）并返回一个可以由目标函数处理的输出。</p>
<h3 id="模型训练"><a href="#模型训练" class="headerlink" title="模型训练"></a>模型训练</h3><p>TextAttack 用户可以使用 textattack train 命令在 nlp 库的任何数据集上训练标准的 LSTM、CNN 和基于变换器的模型，或用户自定义模型。</p>
<h3 id="数据扩充"><a href="#数据扩充" class="headerlink" title="数据扩充"></a>数据扩充</h3><p>在搜索对抗性示例时，TextAttack 的转换会对输入文本产生扰动，并应用约束来验证其有效性。通过引入现有样本的扰动版本，可以重复使用这些工具来显着扩展训练数据集。 textattack augment 命令使用户可以访问许多预打包的方法来扩充他们的数据集。这是一个独立的功能，可以与任何模型或训练框架一起使用。使用 TextAttack 的模型和训练管道时，<code>textattack train --augment</code> 会在训练开始前自动扩展数据集。</p>
<h3 id="对抗训练"><a href="#对抗训练" class="headerlink" title="对抗训练"></a>对抗训练</h3><p>通过 <code>textattack train --attack</code>，攻击配方可用于创建新的对抗样本训练集。在干净的训练集上训练多个时期后，攻击会生成每个输入的对抗版本。这个扰动版本的数据集被替换为原始数据集，并根据模型当前的弱点定期重新生成。生成的模型可以显着增强对训练期间使用的攻击的鲁棒性。</p>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230422221025856.png" alt="image-20230422221025856"></p>
<p>上表显示了针对 TextAttack 中实施的不同攻击配方进行和未进行对抗性训练的标准 LSTM 分类器的准确性。</p>
<h2 id="TextAttack的后台操作"><a href="#TextAttack的后台操作" class="headerlink" title="TextAttack的后台操作"></a>TextAttack的后台操作</h2><p>TextAttack 在后台进行了优化，使实施和运行对抗性攻击变得简单快速。</p>
<h3 id="AttackedText"><a href="#AttackedText" class="headerlink" title="AttackedText"></a>AttackedText</h3><p>NLP 攻击实施的一个常见问题是原始文本在标记化后被丢弃；因此，转换是在文本的标记化版本上执行的。这会导致大写和分词问题。有时攻击会将一个词的一部分换成一个完整的词（例如，将“aren’t”转换为“aren’too”）。</p>
<p>为了解决这个问题，TextAttack 将每个输入存储为一个 AttackedText 对象，该对象包含原始文本和用于在保留标记化的同时转换文本的辅助方法。添加、交换或删除单词时，AttackedText 可以保持正确的标点符号和大写。 AttackedText 还包含常见语言功能的实现，例如将文本拆分为单词、将文本拆分为句子和词性标记。</p>
<h3 id="Caching"><a href="#Caching" class="headerlink" title="Caching"></a>Caching</h3><p>搜索方法经常在搜索的不同点遇到相同的输入。在这些情况下，预先存储值以避免不必要的计算是明智的。对于在攻击期间检查的每个输入，TextAttack 缓存其模型输出，以及它是否通过了所有约束。</p>
<h2 id="相关工作"><a href="#相关工作" class="headerlink" title="相关工作"></a>相关工作</h2><p>cleverhans是一个用于为计算机视觉模型构建对抗样本的库。与 cleverhans 一样，我们旨在提供跨各种模型和数据集生成对抗性示例的方法。在某种意义上，TextAttack 努力成为 NLP 社区的 cleverhans 解决方案。与 cleverhans 一样，TextAttack 中的攻击都实现了一个基本的 Attack 类。然而，虽然 cleverhans 在单独的模块中实施了许多不同的攻击，但 TextAttack 从共享组件库构建攻击。</p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>我们介绍了 TextAttack，这是一个用于测试 NLP 模型稳健性的开源框架。 TextAttack 将攻击定义为四个模块：目标函数、约束列表、转换和搜索方法。这使我们能够从这些模块的先前工作中组合攻击，并在共享环境中比较它们。这些攻击可以重复用于数据增强和对抗训练。随着新攻击的开发，我们会将它们的组件添加到 TextAttack。我们希望 TextAttack 有助于降低进入 NLP 稳健性和数据增强研究的门槛。</p>
<h1 id="OpenAttack"><a href="#OpenAttack" class="headerlink" title="OpenAttack"></a>OpenAttack</h1><p>原文标题：《OpenAttack: An Open-source Textual Adversarial Attack Toolkit》</p>
<p><a target="_blank" rel="noopener" href="https://aclanthology.org/venues/acl/">ACL</a> | <a target="_blank" rel="noopener" href="https://aclanthology.org/venues/ijcnlp/">IJCNLP</a></p>
<h2 id="摘要-1"><a href="#摘要-1" class="headerlink" title="摘要"></a>摘要</h2><p>近年来，文本对抗性攻击已经提出了各种攻击模型，这些模型截然不同，并且使用不同的编程框架和设置来实现。这些事实阻碍了攻击模型的快速利用和公平比较。在本文中，我们提出了一个名为 OpenAttack 的开源文本对抗性攻击工具包来解决这些问题。</p>
<p>与现有的其他文本对抗攻击工具包相比，OpenAttack在支持所有攻击类型、多语言性和并行处理方面具有独特的优势。</p>
<p>其高度包容的模块化设计，不仅支持快速利用现有的攻击模型，而且具有极大的灵活性和可扩展性。 OpenAttack 具有广泛的用途，包括比较和评估攻击模型、测量模型的稳健性、协助开发新的攻击模型以及对抗训练。</p>
<p>代码地址：<a target="_blank" rel="noopener" href="https://github.com/thunlp/OpenAttack">https://github.com/thunlp/OpenAttack</a></p>
<h2 id="引言-1"><a href="#引言-1" class="headerlink" title="引言"></a>引言</h2><p>在自然语言处理（NLP）领域，已经提出了多种对抗性攻击模型。这些模型在受害者模型的可访问性（从完全了解到完全无知）和扰动级别（字符、单词或句子级别）方面各不相同。此外，它们最初被提议在不同的评估协议下针对不同的 NLP 任务攻击不同的受害者模型。</p>
<p>为了应对这些挑战，开发了一个名为 TextAttack的文本对抗性攻击工具包。它在统一框架下实现了多种文本对抗攻击模型，并提供了利用现有攻击模型或设计新攻击模型的接口。</p>
<p>OpenAttack也是一个用于文本对抗攻击的开源工具包。与TextAttack类似，OpenAttack采用模块化设计，将各种攻击模型组装起来，以快速实现现有或新的攻击模型。但OpenAttack与TextAttack的区别和互补主要体现在以下三个方面：</p>
<ol>
<li>支持所有攻击。TextAttack不适合句子级的对抗性攻击，因此，TextAttack 中不包含句子级别的攻击模型。相比之下，OpenAttack 采用了更灵活的框架，支持包括句子级攻击在内的所有类型的攻击。</li>
<li>多语种。TextAttack 仅涵盖英文文本攻击，而 OpenAttack 现在支持英文和中文。其可扩展设计可快速支持更多语言。</li>
<li>多线程处理。OpenAttack额外提供了对攻击模型多进程运行的支持，以提高攻击效率。</li>
</ol>
<p>OpenAttack主要贡献：</p>
<ol>
<li>为攻击模型提供各种方便的基线</li>
<li>使用其全面的评估指标全面评估攻击模型</li>
<li>协助快速开发新的攻击模型</li>
<li>评估 NLP 模型对各种对抗性攻击的鲁棒性</li>
<li>进行对抗训练，通过使用生成的对抗样本丰富训练数据来提高模型的鲁棒性</li>
</ol>
<h2 id="文本对抗攻击的形式和分类"><a href="#文本对抗攻击的形式和分类" class="headerlink" title="文本对抗攻击的形式和分类"></a>文本对抗攻击的形式和分类</h2><p>根据攻击模型对受害者模型的可访问性，现有的攻击模型可以分为四类，即基于梯度的、基于分数的、基于决策的和黑盒模型。</p>
<p>首先，基于梯度的攻击模型也称为白盒攻击模型，需要充分了解受害者模型才能进行梯度更新。与白盒攻击模型相比，黑盒模型不需要拥有关于受害者模型的完整信息，并且可以细分为基于分数的模型、基于决策的模型和盲模型。盲模型根本不知道受害者模型。基于分数的模型需要受害者模型的预测分数（例如，分类概率），而基于决策的模型只需要最终决策（例如，预测的类别）。</p>
<p>根据对原始输入施加的扰动程度，文本对抗攻击模型可以分为句子级、单词级和字符级模型。</p>
<p>句子级攻击模型主要通过添加分散注意力的句子、释义或通过编码器-解码器生成文本。<br>词级攻击模型主要进行词替换，即用语义相同或相似的词替换原始输入中的某些词，例如同义词、删除和添加词。<br>字符级攻击模型通常执行字符操作，包括交换、替换、删除、插入和重复。</p>
<p>最后，根据受害模型给出的错误分类结果是否预先指定（主要针对多类分类模型），对抗性攻击模型也可以分为目标模型和非目标模型。</p>
<p>目前OpenAttack包括15种针对文本分类模型的典型攻击模型，涵盖所有攻击类型。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>Model</th>
<th>Accessibility</th>
<th>Perturbation</th>
<th>Main Idea</th>
</tr>
</thead>
<tbody>
<tr>
<td>SEA</td>
<td>Decision</td>
<td>Sentence</td>
<td>Rule-based paraphrasing</td>
</tr>
<tr>
<td>SCPN</td>
<td>Blind</td>
<td>Sentence</td>
<td>Paraphrasing</td>
</tr>
<tr>
<td>GAN</td>
<td>Decision</td>
<td>Sentence</td>
<td>Text generation by encoder-decoder</td>
</tr>
<tr>
<td>TextFooler</td>
<td>Score</td>
<td>Word</td>
<td>Greedy word substitution</td>
</tr>
<tr>
<td>PWWS</td>
<td>Score</td>
<td>Word</td>
<td>Greedy word substitution</td>
</tr>
<tr>
<td>Genetic</td>
<td>Score</td>
<td>Word</td>
<td>Genetic algorithm-based word substitution</td>
</tr>
<tr>
<td>SememePSO</td>
<td>Score</td>
<td>Word</td>
<td>Particle Swarm Optimization-based word substitution</td>
</tr>
<tr>
<td>BERT-ATTACK</td>
<td>Score</td>
<td>Word</td>
<td>Greedy contextualized word substitution</td>
</tr>
<tr>
<td>BAE</td>
<td>Score</td>
<td>Word</td>
<td>Greedy contextualized word substitution and insertion</td>
</tr>
<tr>
<td>FD</td>
<td>Gradient</td>
<td>Word</td>
<td>Gradient-based word substitution</td>
</tr>
<tr>
<td>TextBugger</td>
<td>Gradient, Score</td>
<td>Word+Char</td>
<td>Greedy word substitution and character manipulation</td>
</tr>
<tr>
<td>UAT</td>
<td>Gradient</td>
<td>Word, Char</td>
<td>Gradient-based word or character manipulation</td>
</tr>
<tr>
<td>HotFlip</td>
<td>Gradient</td>
<td>Word, Char</td>
<td>Gradient-based word or character substitution</td>
</tr>
<tr>
<td>VIPER</td>
<td>Blind</td>
<td>Char</td>
<td>Visually similar character substitution</td>
</tr>
<tr>
<td>DeepWordBug</td>
<td>Score</td>
<td>Char</td>
<td>Greedy character manipulation</td>
</tr>
</tbody>
</table>
</div>
<h2 id="工具包设计和架构"><a href="#工具包设计和架构" class="headerlink" title="工具包设计和架构"></a>工具包设计和架构</h2><p>我们提取并适当重组来自不同攻击模型的常用组件，以便任何攻击模型都可以由它们组装。考虑到不同攻击模型之间的显着区别，尤其是句子级和单词/字符级攻击模型之间的区别，很难将所有攻击模型包含在像 TextAttack 这样的统一框架中。因此，我们为攻击模型的骨架设计留出了相当大的自由度，更专注于简化对抗性攻击的一般流程，并提供攻击模型中使用的通用组件。</p>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230423164028106.png" alt="image-20230423164028106"></p>
<ul>
<li><p>TextProcessor</p>
<p>该模块旨在处理原始输入，以协助攻击模型生成对抗性示例。它由几个用于标记化、词形还原、去词形化、词义消歧 (WSD)、命名实体识别 (NER) 和依赖项解析的函数组成。</p>
</li>
<li><p>Victim</p>
<p>该模块包装了受害者模型。它主要由三个函数组成，用于获取关于受害者模型的输入、预测分数和预测类别的梯度。</p>
</li>
<li><p>Attacker</p>
<p>这是OpenAttack的核心模块。它包含各种攻击模型，并且可以针对受害者模型针对给定输入生成对抗性示例。</p>
</li>
<li><p>AttackAssist</p>
<p>这是Attacker的辅助模块。它主要封装了广泛应用于词级和字符级攻击模型的不同词和字符替换方法。</p>
</li>
<li><p>Metric</p>
<p>该模块提供了几个对抗性示例质量指标，可以作为攻击过程中对抗性示例的约束或评估对抗性攻击的评估指标。</p>
</li>
<li><p>AttackEval</p>
<p>该模块用于从不同角度评估文本对抗攻击，包括攻击有效性、对抗样本质量和攻击效率。</p>
<ul>
<li>攻击有效性指标是攻击成功率，即成功欺骗受害者模型的攻击的百分比；</li>
<li>对抗样本质量由 Metric 模块中的指标来衡量；</li>
<li>攻击效率有两个指标，包括平均受害者模型查询次数和攻击一个实例的平均运行时间。</li>
</ul>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230423164554282.png" alt="image-20230423164554282"></p>
</li>
<li><p>DataManager</p>
<p>该模块管理所有数据以及在其他模块中使用的已保存模型。该模块有助于高效、便捷地利用数据。</p>
</li>
</ul>
<h2 id="工具包使用"><a href="#工具包使用" class="headerlink" title="工具包使用"></a>工具包使用</h2><p>OpenAttack 提供了一组易于使用的接口，几乎可以满足文本对抗攻击中的所有需求。此外，OpenAttack具有极大的灵活性和可扩展性，支持轻松定制受害者模型和攻击模型。</p>
<h3 id="内置攻击和评估"><a href="#内置攻击和评估" class="headerlink" title="内置攻击和评估"></a>内置攻击和评估</h3><p>OpenAttack 内置了一些常用的 NLP 模型，例如 LSTM和 BERT。用户可以使用内置的受害者模型快速进行对抗性攻击。以下代码片段显示了如何使用 Genetic 在 SST-2 测试集上以 4 进程并行运行来攻击 BERT：</p>
<pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token keyword">import</span> OpenAttack <span class="token keyword">as</span> oa
<span class="token keyword">import</span> datasets <span class="token comment"># HuggingFace’s datasets library</span>
<span class="token keyword">import</span> multiprocessing
<span class="token comment"># choose a trained victim model</span>
victim <span class="token operator">=</span> oa<span class="token punctuation">.</span>loadVictim<span class="token punctuation">(</span>’BERT<span class="token punctuation">.</span>SST’<span class="token punctuation">)</span>
<span class="token comment"># choose a evaluation dataset from datasets</span>
dataset <span class="token operator">=</span> datasets<span class="token punctuation">.</span>load_dataset<span class="token punctuation">(</span>’sst’<span class="token punctuation">,</span> ’test’<span class="token punctuation">)</span>
<span class="token comment"># choose Genetic as the attacker</span>
attacker <span class="token operator">=</span> oa<span class="token punctuation">.</span>attackers<span class="token punctuation">.</span>GeneticAttacker<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment"># prepare for multi-process attacking</span>
attack_eval <span class="token operator">=</span> oa<span class="token punctuation">.</span>attack_evals<span class="token punctuation">.</span>MultiProcessAttackEval<span class="token punctuation">(</span>attacker<span class="token punctuation">,</span> victim<span class="token punctuation">,</span> num_process<span class="token operator">=</span><span class="token number">4</span><span class="token punctuation">)</span>
<span class="token comment"># launch attacks and print attack results</span>
attack_eval<span class="token punctuation">.</span><span class="token builtin">eval</span><span class="token punctuation">(</span>dataset<span class="token punctuation">,</span> visualize<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>运行结果：</p>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230423165145432.png" alt="image-20230423165145432"></p>
<h3 id="定制的受害者模型"><a href="#定制的受害者模型" class="headerlink" title="定制的受害者模型"></a>定制的受害者模型</h3><p>用户对自己在特定数据集上训练过的模型发起攻击是很常见的，尤其是在评估受害模型的稳健性时。因此，受害者模型的轻松定制非常重要。</p>
<p>OpenAttack 为受害者模型定制提供了简单方便的接口。对于使用任何编程框架实现的训练模型，用户只需要在 Victim 类下配置一些模型访问接口，提供攻击模型所需的可访问性。</p>
<p>下面的代码片段展示了如何使用 PWWS 在 SST-2 上攻击自定义的情感分析模型（NLTK 内置的统计模型）</p>
<pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token keyword">import</span> OpenAttack <span class="token keyword">as</span> oa
<span class="token keyword">import</span> numpy <span class="token keyword">as</span> np
<span class="token keyword">import</span> datasets
<span class="token keyword">import</span> nltk
<span class="token keyword">from</span> nltk<span class="token punctuation">.</span>sentiment<span class="token punctuation">.</span>vader <span class="token keyword">import</span> SentimentIntensityAnalyzer


<span class="token comment"># configure access interface of customized model</span>
<span class="token keyword">class</span> <span class="token class-name">MyModel</span><span class="token punctuation">(</span>oa<span class="token punctuation">.</span>Victim<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">def</span> <span class="token function">__init__</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
        self<span class="token punctuation">.</span>model <span class="token operator">=</span> SentimentIntensityAnalyzer<span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">def</span> <span class="token function">get_prob</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> input_<span class="token punctuation">)</span><span class="token punctuation">:</span>
        rt <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
        <span class="token keyword">for</span> sent <span class="token keyword">in</span> input_<span class="token punctuation">:</span>
            rs <span class="token operator">=</span> self<span class="token punctuation">.</span>model<span class="token punctuation">.</span>polarity_scores<span class="token punctuation">(</span>sent<span class="token punctuation">)</span>
            prob <span class="token operator">=</span> rs<span class="token punctuation">[</span><span class="token string">"pos"</span><span class="token punctuation">]</span> <span class="token operator">/</span> <span class="token punctuation">(</span>rs<span class="token punctuation">[</span><span class="token string">"neg"</span><span class="token punctuation">]</span> <span class="token operator">+</span> rs<span class="token punctuation">[</span><span class="token string">"pos"</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
            rt<span class="token punctuation">.</span>append<span class="token punctuation">(</span>np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span> <span class="token operator">-</span> prob<span class="token punctuation">,</span> prob<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span>rt<span class="token punctuation">)</span>
<span class="token comment"># choose evaluation dataset</span>
dataset <span class="token operator">=</span> datasets<span class="token punctuation">.</span>load_dataset<span class="token punctuation">(</span>’sst’<span class="token punctuation">,</span>’test’<span class="token punctuation">)</span>
<span class="token comment"># choose the customized victim model</span>
victim <span class="token operator">=</span> MyModel<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment"># choose Genetic as the attack model</span>
attacker <span class="token operator">=</span> oa<span class="token punctuation">.</span>attackers<span class="token punctuation">.</span>GeneticAttacker<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment"># prepare for attacking</span>
attack_eval <span class="token operator">=</span> oa<span class="token punctuation">.</span>attack_evals<span class="token punctuation">.</span>DefaultAttackEval<span class="token punctuation">(</span>attacker<span class="token punctuation">,</span> victim<span class="token punctuation">)</span>
<span class="token comment"># launch attacks and print attack results</span>
attack_eval<span class="token punctuation">.</span><span class="token builtin">eval</span><span class="token punctuation">(</span>dataset<span class="token punctuation">,</span> visualize<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="评估"><a href="#评估" class="headerlink" title="评估"></a>评估</h2><p>我们使用 SST-2 作为评估数据集，并选择 BERT，特别是 BERT_BASE，作为受害者模型。我们只将最大受害者模型查询次数限制为 500。我们使用所有攻击模型的原始默认超参数设置。</p>
<p>下表为在 SST-2 上攻击 BERT 时不同攻击模型的评估结果。 ASR = 攻击成功率，WMR = 仅适用于词级攻击的词修改率，LES = Levenshterin 编辑距离，SemSim = Universal Sentence Encoder 测量的语义相似度，Fluency = GPT-2 疑惑值，Grm = 语法错误数，#Query = 平均受害者模型查询次数，T1和T2分别代表单进程和双进程攻击一个实例的平均运行时间（秒），S = T1/T2为加速比。</p>
<p><img src="https://pluto-1300780100.cos.ap-nanjing.myqcloud.com/img/image-20230423170114343.png" alt="image-20230423170114343"></p>
<h2 id="相关工作-1"><a href="#相关工作-1" class="headerlink" title="相关工作"></a>相关工作</h2><p>在文本方面，几乎没有对抗性攻击库。据我们所知，TextAttack是唯一的此类库。它利用一个相对严谨的框架统一了许多攻击模型，并提供了使用现有攻击模型或设计新攻击模型的接口。正如Introduction中提到的，我们的OpenAttack主要在allattack-type支持、多语言性和并行处理方面与TextAttack不同和互补。</p>
<p>还有一些其他工具包与文本对抗性攻击有关。 TEAPOT是一个开源工具包，用于从保留意义的角度评估文本对抗性示例的有效性。它主要设计用于攻击序列到序列模型，但也可用于文本分类模型。 AllenNLP Interpret 是一个解释 NLP 模型预测的框架，其中对抗性攻击是其解释方法之一。它侧重于 NLP 模型的可解释性，仅包含两种攻击模型。</p>
<h2 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h2><p>在本文中，我们介绍了 OpenAttack，这是一种开源文本对抗性攻击工具包，它在文本对抗性攻击中提供了广泛的功能。由于其在全攻击类型支持、多语言性和并行处理方面的独特优势，它是对现有同类产品的一个很好的补充。此外，它具有很大的灵活性和可扩展性，可以轻松定制受害者模型和攻击模型。</p>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">J Sir</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://jy741.gitee.io/2023/04/22/lun-wen-jing-du-textattack-openattack/">https://jy741.gitee.io/2023/04/22/lun-wen-jing-du-textattack-openattack/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">J Sir</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/%E5%AF%B9%E6%8A%97%E6%94%BB%E5%87%BB/">
                                    <span class="chip bg-color">对抗攻击</span>
                                </a>
                            
                                <a href="/tags/%E6%9C%9F%E5%88%8A%E8%AE%BA%E6%96%87/">
                                    <span class="chip bg-color">期刊论文</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/2023/05/04/lun-wen-jing-du-learning-to-prompt-for-vision-language-models/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/13.jpg" class="responsive-img" alt="论文精读——Learning to Prompt for Vision-Language Models">
                        
                        <span class="card-title">论文精读——Learning to Prompt for Vision-Language Models</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2023-05-04
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-user fa-fw"></i>
                            J Sir
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/%E6%9C%9F%E5%88%8A%E8%AE%BA%E6%96%87/">
                        <span class="chip bg-color">期刊论文</span>
                    </a>
                    
                    <a href="/tags/%E6%8F%90%E7%A4%BA%E5%AD%A6%E4%B9%A0/">
                        <span class="chip bg-color">提示学习</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/2023/04/13/mu-biao-jian-ce-yolo-xi-lie-v1-v3/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/16.jpg" class="responsive-img" alt="目标检测——yolo系列（v1~v3）">
                        
                        <span class="card-title">目标检测——yolo系列（v1~v3）</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2023-04-13
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-user fa-fw"></i>
                            J Sir
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">
                        <span class="chip bg-color">深度学习</span>
                    </a>
                    
                    <a href="/tags/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/">
                        <span class="chip bg-color">目标检测</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h1, h2, h3, h4, h5'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h1, h2, h3, h4, h5').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>


<script src="https://cdn.bootcss.com/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
    MathJax.Hub.Config({
        tex2jax: {inlineMath: [['$', '$'], ['\(', '\)']]}
    });
</script>



    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
        left: -66px !important;
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
        left: 0px !important;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="503838841"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.7'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2020-2023</span>
            
            <span id="year">2020</span>
            <a href="/about" target="_blank">J Sir</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">300.9k</span>&nbsp;字
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">


    <a href="mailto:2065373132@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2065373132" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 2065373132" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>







    <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
        <i class="fas fa-rss"></i>
    </a>

</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

	
    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"live2d-widget-model-hibiki"},"display":{"position":"right","width":145,"height":315},"mobile":{"show":true,"scale":0.5},"react":{"opacityDefault":0.7,"opacityOnHover":0.8},"log":false});</script></body>

</html>
